package com.yonyou.pmclouds.workflow.util;

import com.fasterxml.jackson.databind.JsonNode;
import com.yonyou.pmclouds.basecom.billstatus.BillStatusConst;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.entity.SuperVO;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.messagenotice.entity.MessageNoticeVO;
import com.yonyou.pmclouds.messagenotice.rmiitf.MessageNoticeMaintain;
import com.yonyou.pmclouds.task.rmiitf.TaskRemoteService;
import com.yonyou.pmclouds.workflow.entity.ApproveInfoParam;
import com.yonyou.pmclouds.workflow.entity.ProcessTaskVO;
import com.yonyou.pmclouds.workflow.service.ProcessApprovalRecordService;
import com.yonyou.pmclouds.workflow.service.ProcessRuntimeService;
import com.yonyou.pmclouds.workflow.service.ProcessTaskService;
import com.yonyou.pmclouds.workflow.service.rmiitf.IFlowApprove;
import com.yonyou.pmclouds.workflow.service.rmiitf.IWorkFlowService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import yonyou.bpm.rest.request.task.TaskQueryParam;

import java.util.List;

/**
 *  异步调用驳回操作
 *  @author zhangzhonghao
 */

@Component
@Slf4j
public class RejectFlowExecutor extends BatchExecutor{

    @Autowired
    private ProcessTaskService processTaskService;

    @Autowired
    private ProcessApprovalRecordService approvalRecordService;

    @Autowired
    private ProcessRuntimeService processRuntimeService;

    @Autowired
    private IFlowApprove flowApprove;

    @Autowired
    private MessageNoticeMaintain noticeMaintain;

    @Autowired
    private TaskRemoteService taskRemoteService;

    @Autowired
    private IWorkFlowService workFlowService;

    @Override
    public Object executeTaskImpl(Object value) {
        if(value == null){
            return null;
        }
        ApproveInfoParam approveInfoParam = (ApproveInfoParam) value;
        RuntimeEnvironment.setTenantId(approveInfoParam.getTenantId());
        RuntimeEnvironment.setLoginUserId(approveInfoParam.getUserId());

        try{
            ProcessTaskVO[] processTaskVOs = getLatestBillTask(approveInfoParam.getPkBill(), RuntimeEnvironment.getLoginUserId());

            if (ArrayUtils.isEmpty(processTaskVOs))
                throw new BusinessException("用户没有该单据的审批任务，请刷新后重试");

            String activityId = approvalRecordService.getFirstNodeId(RuntimeEnvironment.getLoginUserId(),
                    approveInfoParam.getTenantId(), approveInfoParam.getPkBill());

            JsonNode jsonNode = processRuntimeService.rejectToActivity(processTaskVOs[0].getProcessInstanceId(),
                    approveInfoParam.getOpinion(), processTaskVOs[0].getTaskId(), activityId);

            log.debug("驳回返回值：" + jsonNode.toString());

            boolean result = flowApprove.reject(approveInfoParam);
            // 四种单据类型驳回时不发送通知：综合验收，施工记录，签证申请，变更申请
            if (result && !BillTypeConst.COMPREHENSIVE_ACCEPTANCE_BILLTYPE.equals(approveInfoParam.getBillType())
                    && !BillTypeConst.CONSTRUCTIONLOG_BILLTYPE.equals(approveInfoParam.getBillType())
                    && !BillTypeConst.ALTER_AND_VISA_BILLTYPE.equals(approveInfoParam.getBillType())
                    && !BillTypeConst.ALTER_BILLTYPE.equals(approveInfoParam.getBillType())) {
                // 驳回时给制单人发送消息提醒
                MessageNoticeVO noticeVO = new MessageNoticeVO();
                noticeVO.setRelateKey(approveInfoParam.getPkBill());
                noticeVO.setRelateType(approveInfoParam.getBillType());
                noticeMaintain.insertMessageNotice(noticeVO);
            }
            return value;
        }catch (Exception e){
            log.error("驳回操作失败：", e);
            // 将已办回滚为待办
            List<String> pkTasks = approveInfoParam.getPkTasks();
            if(pkTasks != null && pkTasks.size() > 0){
                try {
                    taskRemoteService.updateTaskStatus(pkTasks);
                } catch (BusinessException e1) {
                    log.error("驳回失败后回滚待办消息：", e);
                }
            }

            try {
                workFlowService.updateBillStatus(approveInfoParam.getBillType(), approveInfoParam.getPkBill(), BillStatusConst.COMMON_APPROVING_STATUS);
            } catch (BusinessException e1) {
                log.error("驳回单据信息失败：", e1);
            }
            return null;
        }
    }

    private ProcessTaskVO[] getLatestBillTask(String pkBill, String pkUser) throws BusinessException {
        TaskQueryParam taskQueryParam = getTaskQueryParam(pkBill, pkUser);
        return processTaskService.queryProcessTaskVOs(taskQueryParam);
    }

    private TaskQueryParam getTaskQueryParam(String pkBill, String pkUser) {
        TaskQueryParam taskQueryParam = new TaskQueryParam();
        taskQueryParam.setProcessInstanceBusinessKey(pkBill);
        taskQueryParam.setAssignee(pkUser);
        return taskQueryParam;
    }
}
